﻿//===========================[ 7 / 25 / 2011 LVI ]=============================
//				Copyright c Vitaly Lyaschenko <SkyChameleon@gmail.com>
//								Source file
// Purpose: 
//
//=============================================================================

#include "cGenGeometry.h"

void createCube( float size )
{
	uint i;

	uint numVertices = 24;
	uint numIndices = 36;

	float Vertices[] =
	{
		-1.0f, -1.0f, -1.0f, +1.0f,
		-1.0f, -1.0f, +1.0f, +1.0f,
		+1.0f, -1.0f, +1.0f, +1.0f,
		+1.0f, -1.0f, -1.0f, +1.0f,
		-1.0f, +1.0f, -1.0f, +1.0f,
		-1.0f, +1.0f, +1.0f, +1.0f,
		+1.0f, +1.0f, +1.0f, +1.0f,
		+1.0f, +1.0f, -1.0f, +1.0f,
		-1.0f, -1.0f, -1.0f, +1.0f,
		-1.0f, +1.0f, -1.0f, +1.0f,
		+1.0f, +1.0f, -1.0f, +1.0f,
		+1.0f, -1.0f, -1.0f, +1.0f,
		-1.0f, -1.0f, +1.0f, +1.0f,
		-1.0f, +1.0f, +1.0f, +1.0f,
		+1.0f, +1.0f, +1.0f, +1.0f,
		+1.0f, -1.0f, +1.0f, +1.0f,
		-1.0f, -1.0f, -1.0f, +1.0f,
		-1.0f, -1.0f, +1.0f, +1.0f,
		-1.0f, +1.0f, +1.0f, +1.0f,
		-1.0f, +1.0f, -1.0f, +1.0f,
		+1.0f, -1.0f, -1.0f, +1.0f,
		+1.0f, -1.0f, +1.0f, +1.0f,
		+1.0f, +1.0f, +1.0f, +1.0f,
		+1.0f, +1.0f, -1.0f, +1.0f
	};

	float cubeNormals[] =
	{
		0.0f, -1.0f,  0.0f,
		0.0f, -1.0f,  0.0f,
		0.0f, -1.0f,  0.0f,
		0.0f, -1.0f,  0.0f,
		0.0f, +1.0f,  0.0f,
		0.0f, +1.0f,  0.0f,
		0.0f, +1.0f,  0.0f,
		0.0f, +1.0f,  0.0f,
		0.0f,  0.0f, -1.0f,
		0.0f,  0.0f, -1.0f,
		0.0f,  0.0f, -1.0f,
		0.0f,  0.0f, -1.0f,
		0.0f,  0.0f, +1.0f,
		0.0f,  0.0f, +1.0f,
		0.0f,  0.0f, +1.0f,
		0.0f,  0.0f, +1.0f,
		-1.0f,  0.0f,  0.0f,
		-1.0f,  0.0f,  0.0f,
		-1.0f,  0.0f,  0.0f,
		-1.0f,  0.0f,  0.0f,
		+1.0f,  0.0f,  0.0f,
		+1.0f,  0.0f,  0.0f,
		+1.0f,  0.0f,  0.0f,
		+1.0f,  0.0f,  0.0f
	};

	float cubeTexCoords[] =
	{
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
		1.0f, 0.0f,
		1.0f, 1.0f,
		0.0f, 1.0f,
		0.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
	};

	_16ubit cubeIndices[] =
	{
		0, 2, 1,
		0, 3, 2, 
		4, 5, 6,
		4, 6, 7,
		8, 9, 10,
		8, 10, 11, 
		12, 15, 14,
		12, 14, 13, 
		16, 17, 18,
		16, 18, 19, 
		20, 23, 22,
		20, 22, 21
	};
}

// http://www.gamedev.ru/code/forum/?id=147171#m4
bool createCylinder ( float diameter, float length, size_t facet, 
	std::vector < vec3 >& vertex, std::vector < _16ubit >& index, float& volume ) 
{
	vertex.reserve ( facet * 2 ) ;
	index.reserve ( facet * 12 ) ;

	//радиус
	const float R = diameter / 2.0f ;

	//половина длины
	const float L = length / 2.0f ;

	const float AndleStep = _mtl::degreesToRadians( 360.0f / facet ) ;

	//первая боковая поверхность
	float Step = 0.0f ;
	for ( size_t i = 0 ; i != facet ; ++ i )
	{  
		vertex.push_back ( vec3 ( L , R * cos ( Step ) , R * sin ( Step ) ) ) ;    
		Step += AndleStep ;
	}
	for ( size_t i = 0 ; i != facet - 2 ; ++ i )
	{
		index.push_back ( 0 ) ;
		index.push_back ( i + 1 ) ;
		index.push_back ( i + 2 ) ;
	}
	//вторая боковая поверхность
	Step = 0.0f ;
	for ( size_t i = 0 ; i != facet ; ++ i )
	{  
		vertex.push_back ( vec3 ( - L , R * cos ( Step ) , R * sin ( Step ) ) ) ;    
		Step += AndleStep ;
	}
	for ( size_t i = 0 ; i != facet - 2 ; ++ i )
	{
		index.push_back ( i + facet + 2 ) ;
		index.push_back ( i + facet + 1 ) ;
		index.push_back ( facet ) ;
	}
	//поверхность
	for ( size_t i = 0 ; i != facet ; ++ i )
	{
		size_t Index = i + facet + 1 ;

		if ( Index == facet * 2 )
			Index = facet ;

		index.push_back ( i ) ;
		index.push_back ( i + facet ) ;
		index.push_back ( Index ) ;

		index.push_back ( i ) ;
		index.push_back ( Index ) ;
		index.push_back ( ( i + 1 ) % facet ) ;
	}

	//расчёт объёма
	const float Footprint = ( facet / 2.0f ) * R * R * sin ( 2.0f * _mtl::PI / facet ) ;
	volume = Footprint * length ;

	return true;
}